package com.yeskery.nut.extend.i18n;

import com.yeskery.nut.core.*;
import com.yeskery.nut.plugin.ApplicationContextSupportBasePlugin;
import com.yeskery.nut.plugin.InterceptorPlugin;
import com.yeskery.nut.plugin.PluginBeanMetadata;
import com.yeskery.nut.util.StringUtils;

import java.util.*;

/**
 * 国际化插件
 * @author sprout
 * 2022-05-28 17:04
 */
public class I18nPlugin extends ApplicationContextSupportBasePlugin implements InterceptorPlugin {

    /** 国际化资源名称 */
    public static final String I18N_LOCALES = "i18n_locales";

    /** 国际化语言请求头 */
    private static final String ACCEPT_LANGUAGE_HEADER = "Accept-Language";

    /** 国际化资源路径 */
    private String path;

    /**
     * 构建国际化插件
     */
    public I18nPlugin() {
    }

    /**
     * 构建国际化插件
     * @param path 国际化资源路径
     */
    public I18nPlugin(String path) {
        this.path = path;
    }

    @Override
    protected Collection<PluginBeanMetadata> getRegisterPluginBeanMetadata() {
        MessageService messageService = StringUtils.isEmpty(path)
                ? new DefaultMessageServiceImpl()
                : new DefaultMessageServiceImpl(path);
        return Collections.singleton(new PluginBeanMetadata("messageService", messageService,
                MessageService.class, DefaultMessageServiceImpl.class));
    }

    @Override
    public boolean beforeHandle(Request request, Response response, Execution execution, Controller controller) throws Exception {
        List<String> headers = request.getHeaders(ACCEPT_LANGUAGE_HEADER);
        if (headers == null || headers.isEmpty()) {
            return true;
        }
        Set<Locale> locales = new LinkedHashSet<>();
        for (String header : headers) {
            if (StringUtils.isEmpty(header)) {
                continue;
            }
            String[] languages = header.split(",");
            for (String language : languages) {
                String[] weightLanguages = language.split(";");
                if (weightLanguages.length == 0) {
                    continue;
                }
                String[] localeLanguages = weightLanguages[0].split(",");
                for (String localeLanguage : localeLanguages) {
                    if (localeLanguage.contains("-")) {
                        String[] splits = localeLanguage.split("-");
                        if (splits.length == 2 && !StringUtils.isEmpty(splits[0]) && !StringUtils.isEmpty(splits[1])) {
                            locales.add(new Locale(splits[0], splits[1]));
                        }
                    } else {
                        locales.add(new Locale(localeLanguage));
                    }
                }
            }
        }

        if (!locales.isEmpty()) {
            RequestApplicationContext.putResource(I18N_LOCALES, locales);
        }
        return true;
    }

    @Override
    public int getOrder() {
        return -1;
    }
}
